package com.example.nick.bodyapplication

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import com.example.nick.bodyapplication.databinding.ActivityFlowBinding
import com.example.nick.bodyapplication.jetpack.flow.FlowViewModel
import com.example.nick.bodyapplication.jetpack.flow.TFlowVM
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

data class Event(val count: Int)

class FlowActivity : AppCompatActivity() {

    val viewModel2 = viewModels<TFlowVM>()

    val TAG = "Flow"
    lateinit var vb: ActivityFlowBinding
    lateinit var flow: Flow<Int>
    lateinit var flow2: Flow<Int>
    var job: Job? = null
    var shareFlow = MutableSharedFlow<Event>()
    val stateFlow = MutableStateFlow(1)
    val sendStateFlow = MutableStateFlow(1)
    var sendJob: Job? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "onCreate")
        vb = ActivityFlowBinding.inflate(layoutInflater)
        setContentView(vb.root)
        setupFlow()
        //viewModel2.aaa
    }

    fun setupFlow() {
        var list = listOf(1, 2, 3, 4, 5)
        flow2 = list.asFlow().flowOn(Dispatchers.Default).map {
            it * it
            Log.d(TAG, "Emitting2: $it, thread:${Thread.currentThread()}")
        }
        flow = flow {
            Log.d(TAG, "Start flow")
            (0..5).forEach {
                // Emit items with 500 milliseconds delay
                delay(1000)
                Log.d(TAG, "Emitting $it, thread:${Thread.currentThread()}")
                emit(it)
            }
        }.flowOn(Dispatchers.Default)
        lifecycleScope.launchWhenStarted {
            shareFlow.emit(Event(1))
            delay(1000)
            shareFlow.emit(Event(2))
            delay(1000)
            shareFlow.emit(Event(3))
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart")
        lifecycleScope.launchWhenStarted {
            shareFlow.collect {
                Log.d(TAG, "shared 1 collect: $it thread:${Thread.currentThread()}")
            }
        }
//        lifecycleScope.launch(Dispatchers.IO) {
//            while (lifecycle.currentState == Lifecycle.State.STARTED || lifecycle.currentState == Lifecycle.State.RESUMED) {
//                delay(500)
//                Log.d(TAG, "launchWhenStarted: thread:${Thread.currentThread()}")
//            }
//        }
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume")
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause")
    }

    override fun onStop() {
        super.onStop()
        Log.d(TAG, "onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy")
    }

    fun onCollect(view: View) {
//        lifecycleScope.launchWhenResumed {
//            flow.collect {
//                Log.d(TAG, "collect: $it thread:${Thread.currentThread()}")
//            }
//        }
//        job = CoroutineScope(Dispatchers.Main).launch {
//            flow.collect {
//                Log.d(TAG, "collect: $it thread:${Thread.currentThread()}")
//            }
////            flow2.collect {
////                Log.d(TAG, "collect2: $it thread:${Thread.currentThread()}")
////            }
//        }
//        lifecycleScope.launchWhenStarted {
//            shareFlow.collect {
//                Log.d(TAG, "shared 2 collect: $it thread:${Thread.currentThread()}")
//            }
//        }
        lifecycleScope.launchWhenStarted {
//            stateFlow.collect {
//                Log.i(TAG, "state 2 collect: $it thread:${Thread.currentThread()}")
//            }
            sendStateFlow.collect {
                Log.i(TAG, "send 2 collect: $it thread:${Thread.currentThread()}")
            }
        }
    }

    var count = 0
    fun onEmit(view: View) {
//        job?.let {
//            it.cancel()
//        }
//        flow.map { it * it }
//
//        lifecycleScope.launchWhenStarted {
//            shareFlow.emit(4)
//            delay(1000)
//            shareFlow.emit(5)
//            delay(1000)
//            shareFlow.emit(6)
//        }

//        lifecycleScope.launchWhenStarted {
//            stateFlow.emit(++count)
//        }

//        lifecycleScope.launch(Dispatchers.IO) {
//            while (true) {
//                stateFlow.emit(++count)
//                Log.d(TAG, "state emit: $count thread:${Thread.currentThread()}")
//                delay(500)
//            }
//        }

//        lifecycleScope.launchWhenStarted {
//            while (true) {
//                withContext(Dispatchers.IO) {
//                    stateFlow.emit(++count)
//                    Log.d(TAG, "state emit: $count thread:${Thread.currentThread()}")
//                    delay(500)
//                }
//            }
//        }
//        sendJob = lifecycleScope.launchWhenStarted {
//            while (!crash) {
//                withContext(Dispatchers.IO) {
//                    delay(1000)
////                    if (crash) {
////                        sendStateFlow.emit(110)
////                        Log.d(TAG, "send emit: $count thread:${Thread.currentThread()}")
////                        sendJob?.cancel()
////                    }
//                    count++
//                    Log.d("Flow", "Flow TimerTick count:$count")
//                    TimerTick.delaySend(3000)
//                    if (count == 10) {
//                        crash = true
//                    }
//
//                }
//            }
//        }
    }

    var crash = false
    fun onCrash(view: View) {
        TimerTick.cancel()
//        crash = true
//        runBlocking(Dispatchers.IO) {
//            Log.i("Flow", "Flow delay 1000 threa:${Thread.currentThread()}")
////            while (true) {
////
////            }
//            delay(1000)
//        }

//        var cc = 0
//        lifecycleScope.launch {
//            withContext(Dispatchers.IO) {
//                Log.i("Flow", "Flow delay 1000 threa:${Thread.currentThread()}")
//                launch {
//                    while (++cc < 5) {
//                        delay(1000)
//                        Log.d("Flow", "Flow delay 1000 in thread:${Thread.currentThread()}")
//                    }
//                }
//                Log.e("Flow", "Flow delay 1000 threa:${Thread.currentThread()}")
//            }
//        }
//        Log.e("Flow", "Flow delay 1000 out threa:${Thread.currentThread()}")


    }

    ////        lifecycle
    //        lifecycle.addObserver(GenericLifecycleObserver { source, event ->
    //            Log.d(TAG, "onStateChanged: event =$event")
    //        })
    //        lifecycle.addObserver(object : DefaultLifecycleObserver {
    //            override fun onCreate(owner: LifecycleOwner) {
    //                super.onCreate(owner)
    //                Log.d(TAG, "lifecycle onCreate")
    //            }
    //
    //            override fun onStart(owner: LifecycleOwner) {
    //                super.onStart(owner)
    //                Log.d(TAG, "lifecycle onStart")
    //            }
    //
    //            override fun onResume(owner: LifecycleOwner) {
    //                super.onResume(owner)
    //                Log.d(TAG, "lifecycle onResume")
    //            }
    //
    //            override fun onPause(owner: LifecycleOwner) {
    //                super.onPause(owner)
    //                Log.d(TAG, "lifecycle onPause")
    //            }
    //
    //            override fun onStop(owner: LifecycleOwner) {
    //                super.onStop(owner)
    //                Log.d(TAG, "lifecycle onStop")
    //            }
    //
    //            override fun onDestroy(owner: LifecycleOwner) {
    //                super.onDestroy(owner)
    //                Log.d(TAG, "lifecycle onDestroy")
    //            }
    //        })

}